#include "base/assert.hpp"
#include "event/fd_event.hpp"
#include "event/loop.hpp"
#include "fmt/core.h"
#include "network/buffered_fd.hpp"

#include <cstdint>
#include <memory>
#include <unistd.h>

using namespace ibox::event;
using namespace ibox::network;

int main() {
    auto loop = Loop();

    EpollFdEvent read_fd{
        loop.ptr(), STDIN_FILENO, FdEvent::ReadEvent, Event::Mode::Forever};
    EpollFdEvent write_fd{
        loop.ptr(), STDOUT_FILENO, FdEvent::WriteEvent, Event::Mode::Oneshot}; // 可写事件单次有效

    // 可读一直开着.
    read_fd.enable();

    // 发送缓存
    char buf[64];

    read_fd.set_callback([&](uint32_t events) {
        if (static_cast<bool>(events & FdEvent::ReadEvent)) {
            auto size = read(STDIN_FILENO, buf, sizeof(buf));
            buf[size - 1] = '\0';
            fmt::print("INPUT: {}\n", buf);
            write_fd.enable();
        }
    });

    write_fd.set_callback([&](uint32_t events) {
        if (static_cast<bool>(events & FdEvent::WriteEvent)) {
            auto size = write(STDOUT_FILENO, buf, strlen(buf));
            if (size > 0) {
                memmove(buf, buf + size, size);
                if (strlen(buf) > 0) {
                    write_fd.enable();
                }
            }
        }
    });

    loop.run();
}
